#pragma once
#include <atlcoll.h>

template <typename Value>
class CElementTree
{
	Value			m_Value;
	CAtlList<CElementTree> m_Elements;
	CElementTree*	m_pParent;
public:

	CElementTree() : m_pParent(NULL)
	{
	}

	CElementTree(const CElementTree & item) :
		m_Value(item.m_Value), m_pParent(item.m_pParent)
	{
		m_Elements.AddHeadList(&item.m_Elements);
	}

	CElementTree(CElementTree* pParent, Value val) :
		 m_pParent(pParent), m_Value(val)
	{
	}

	~CElementTree()
	{
	}


	inline const Value & GetValue() const { return m_Value; }
	inline Value & GetValue() { return m_Value; }
	inline CElementTree* GetParent() const { return m_pParent; }
	
	inline POSITION GetHeadPosition() const { return m_Elements.GetHeadPosition(); 	}
	inline CElementTree<Value> & GetNext(POSITION & pos) { return m_Elements.GetNext(pos); }

	inline POSITION Find(const Value & val) const;

	inline POSITION AddTail(const Value & val) 	{ return m_Elements.AddTail(CElementTree(this, val)); }

	inline CElementTree<Value> & GetAt(POSITION pos) { return m_Elements.GetAt(pos); }
	inline size_t ChildrenCount() const { return m_Elements.GetCount(); }

	inline void RemoveChildren() {	m_Elements.RemoveAll();	};
};

template <typename Value>
inline POSITION CElementTree<Value>::Find(const Value & val) const
{	
	POSITION pos = m_Elements.GetHeadPosition();
	while(pos)
	{
		POSITION posPrev = pos;
		if (m_Elements.GetNext(pos).m_Value == val)
			return posPrev;
	}
	return NULL;
}
